package com.gonsin.gnews;

import com.gonsin.gnews.annotations.GNewsEnvironment;
import com.gonsin.gnews.annotations.model.NewsStructPo;
import com.gonsin.gnews.annotations.GNews;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.annotation.PostConstruct;
import java.util.*;

@Configuration
@Slf4j
@ComponentScan
@EnableConfigurationProperties
@EnableJpaRepositories
@EntityScan
@EnableCaching
@MapperScan("com.gonsin.gnews.mapper")
public class NewsConfig {

    private Map<String, Set<NewsStructPo>> newsStructs = new HashMap<>();

    /**
     * key = Class
     * value = 配置类表单结构
     */
    private Map<Class, NewsStructPo> structMap = new HashMap<>();

    /**
     * key = platform
     * value = 配置类表单结构
     */
    private Map<String, NewsStructPo> platformMap = new HashMap<>();


    /**
     * 初始化消息结构体
     * 扫描@GNews标注的类，存储到内存中
     */
    @PostConstruct
    public void initNewsStruct(){
        long now = System.currentTimeMillis();
        if(GNewsEnvironment.LOG){
            log.info("GNews - 初始化GNews，扫描范围{}", GNewsApplication.getScanPackage());
        }
        NewsUtils.scannerPackage(GNewsApplication.getScanPackage(), new TypeFilter[]{
                new AnnotationTypeFilter(GNews.class),
        }, clazz -> {
            if(GNewsEnvironment.LOG){
                log.info("GNews - 扫描到{}", clazz.getName());
            }
            NewsStructPo newsStruct = new NewsStructPo(clazz);
            for(String type : newsStruct.getUserType()){
                newsStructs.computeIfAbsent(type, k -> new HashSet<>()).add(newsStruct);
            }
            structMap.put(newsStruct.getTemplateClass(), newsStruct);
        });

        if(GNewsEnvironment.LOG){
            log.info("GNews - 初始化GNews完成，用时{} ms", System.currentTimeMillis() - now);
        }


    }


    /**
     * 根据类查找消息结构
     */
    public NewsStructPo getNewsStruct(Class<?> clazz) {
        return structMap.get(clazz);
    }

    /**
     * 通过用户类型显示用户支持的消息模板
     */
    public List<NewsStructPo> getAllNewsStruct(String userType) {
        return new ArrayList<>(newsStructs.get(userType));
    }
}
